package com.kk.utils.encryption.simple;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * the type of advance
 *
 * <p>
 * 单向加密，不需要key.
 * 只能加密，不能解密.
 *
 * @author MH
 */
public class MD5Utils {
    private static final Logger LOGGER = LoggerFactory.getLogger("MD5Utils");

    /**
     * 标准的MD5加密
     *
     * @param data
     * @return
     */
    public static String encryMD5(String data) {
        MessageDigest md5;
        try {
            md5 = MessageDigest.getInstance("MD5");
            LOGGER.info("==> 待加密: {}", data);
            byte[] digest = md5.digest(data.getBytes(StandardCharsets.UTF_8));
            int i;
            StringBuilder builder = new StringBuilder(32);
            for (byte b : digest) {
                i = b;
                // byte负数转int正数
                if (i < 0) {
                    /* 另一种写法,在if上边: i = b & 0xff */
                    i += 256;
                }
                // 不足16的前面添 "0";
                if (i < 16) {
                    builder.append("0");
                }
                builder.append(Integer.toHexString(i));
            }
            String md5Str = builder.toString();

            LOGGER.info("==> MD5 加密后: {}", md5Str);
            return md5Str;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 加密失败！");
        }
    }

    /**
     * 加盐：1.随机盐值  2.固定盐值
     *
     * @param data
     * @return
     */
    public static String encryMD5_salt(String data) {
        MessageDigest md5;
        try {
            md5 = MessageDigest.getInstance("MD5");
            LOGGER.info("==> 待解密: {}", data);
            // digest固定长度32，加盐
            byte[] digest = md5.digest((data + "username").getBytes());
            int i;
            StringBuilder builder = new StringBuilder(32);
            for (byte b : digest) {
                // 去除byte负数
                i = b & 0xff;
                // 不足16的前面添 "0";
                if (i < 16) {
                    builder.append("0");
                }
                // 转为16进制字符串
                builder.append(Integer.toHexString(i));
            }
            String md5Str = builder.toString();

            LOGGER.info("==> MD5 解密后: {}", md5Str);
            return md5Str;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 加密失败！");
        }
    }

    public static void main(String[] args) {
        String s = encryMD5("");

        String s1 = encryMD5_salt("你好");
    }
}
